import type { ConfigState, EditApiProps } from '@/types/hooks/useEdit'
import type { FormBuldProps } from '@/components/NFormBuilder/index.vue'
import type { IFormItem } from '@/components/NFormBuilder/types'
import type { FormRules } from 'naive-ui'
import type { useEditBack } from '@/types/hooks/useTable'
import { NScrollbar, NButton, NConfigProvider, darkTheme, zhCN, dateZhCN } from 'naive-ui'
import { themesStore } from '@/stores/modules/theme'
import { storeToRefs } from 'pinia'
import { cloneDeep, isNumber, isString, omit } from 'lodash-es'
import { drawer } from '@/service/drawer/drawer'
import MacHeader from '@/components/codeBlock/MacHeader.vue'
import NFormBuilder from '@/components/NFormBuilder/index.vue'
import http from '@/service/http'

export function useEdit(config: ConfigState): useEditBack {
  const { apis } = config
  const key = config?.key || 'id'
  const type = config?.type || 'model'
  const setDefaultValue = (row) => {
    config.defaultValue = row
  }
  /**
   * 动态表单相关
   * */
  const formData = ref<Record<string, unknown>>({})
  const formInstance = ref()
  const handleValidateClick = async (e: MouseEvent) => {
    e.preventDefault()
    try {
      await formInstance.value?.validate()
      save()
    } catch (error) {
      if (config?.errTip) {
        msgUtil.$message.error(error[0][0].message)
      }
      return
    }
  }

  const getApiConfig = (type: 'add' | 'edit') => {
    const apiConfig: EditApiProps = {
      api: '',
      method: 'post',
      successText: type === 'add' ? '添加成功' : '编辑成功',
    }
    if (type === 'add') {
      if (isString(config.addApi)) {
        apiConfig.api = config.addApi as string
        return apiConfig
      }
      Object.assign(apiConfig, config.addApi)
      return apiConfig
    }
    if (!config.editApi) {
      // 未配置edit, 默认和addApi相同
      const addConfig = getApiConfig('add')
      delete addConfig.successText
      return Object.assign(apiConfig, addConfig)
    }
    if (isString(config.editApi)) {
      apiConfig.api = config.editApi as string
      return apiConfig
    }
    return Object.assign(apiConfig, config.editApi)
  }

  const doRequest = async (params) => {
    delete params.delFlag
    const isEdit = !!formData.value[key]
    if (config?.saveParams) {
      params = config.saveParams(params)
    }
    if (config.addApi) {
      // 新版本接口请求
      const apiConfig: EditApiProps = getApiConfig(isEdit ? 'edit' : 'add')
      const { code, msg } = await http[apiConfig.method](apiConfig.api, params)
      if (code !== 0) {
        msgUtil.$message.error(msg)
        return
      }
      config?.[isEdit ? 'editChange' : 'addChange']?.(params)
      msgUtil.$message.success(apiConfig.successText)
    } else {
      // 老版本接口请求
      const { code, msg } = isEdit ? await apis.doEdit.api(params) : await apis.doAdd.api(params)
      if (code !== 0) {
        requestLoading = false
        msgUtil.$message.error(msg)
        return
      }
      config?.[isEdit ? 'editChange' : 'addChange']?.(params)
      const addSuccessText = apis?.doAdd?.successText || '添加成功'
      const editSuccessText = apis?.doEdit?.successText || '编辑成功'
      msgUtil.$message.success(isEdit ? editSuccessText : addSuccessText)
    }
    config?.successChange?.(params)
    close()
  }

  let requestLoading = false
  const save = async () => {
    if (requestLoading) return
    requestLoading = true
    try {
      await doRequest(deepClone(formData.value))
    } finally {
      requestLoading = false
    }
  }

  const setFormItems = (formItems: IFormItem[] | Ref<IFormItem[]>) => {
    config.props.formItems = formItems
  }

  const setRules = (rules: FormRules | Ref<FormRules>) => {
    config.props.rules = rules
  }

  /**
   * 指令弹框
   * */
  let modal
  const state = reactive({
    title: '添加',
    width: config?.width || 500,
  })
  const close = () => {
    if (type === 'model') modal?.destroy()
    else drawer?.close()
  }
  const theme = themesStore()
  const { getThemeOverrides: themeOverrides, getIsDark: isDark } = storeToRefs(theme)
  const themeInfo = computed(() => {
    return isDark.value ? darkTheme : undefined
  })
  const diyTheme = (domFn: () => Component) => {
    return h(
      NConfigProvider,
      {
        abstract: true,
        theme: themeInfo.value,
        themeOverrides: themeOverrides.value as Record<string, unknown>,
        locale: zhCN,
        dateLocale: dateZhCN,
      },
      domFn,
    )
  }
  const setTitle = (type: 'add' | 'edit', title?: string) => {
    if (title) {
      state.title = title
      return true
    }
    if (config?.title) {
      if (isString(config.title)) {
        state.title = type === 'add' ? `添加${config.title}` : `编辑${config.title}`
      } else {
        state.title = config.title()
      }
      return true
    }
    state.title = type === 'add' ? '添加' : '编辑'
  }

  const open = (data?: Record<string, unknown>, title?: string) => {
    setTitle(data && data[key] ? 'edit' : 'add', title)
    if (data) {
      formData.value = cloneDeep(data)
    } else {
      formData.value = config?.defaultValue ? cloneDeep(config.defaultValue) : {}
    }

    // 底部按钮元素
    const toolNode = h(
      'div',
      { class: 'tools w-full flex items-center justify-end', style: { gap: '10px' } },
      [
        h(NButton, { onClick: close }, () => '取消'),
        h(NButton, { type: 'primary', onClick: handleValidateClick }, () => '提交'),
      ],
    )

    // 动态表单元素
    const props: FormBuldProps = reactive({
      formItems: [],
      ...omit(config.props, ['createItems', 'createRule']),
    })
    if (config?.createItems) {
      props.formItems = config.createItems({
        formData,
        ...config.extended,
      })
    }
    if (config?.createRule) {
      props.rules = config.createRule({
        formData,
        ...config.extended,
      })
    }
    if (type === 'model') {
      modal = msgUtil.$modal.create({
        preset: 'card',
        bordered: false,
        closable: false,
        contentStyle: {
          padding: '0',
        },
        style: {
          width: isNumber(state.width) ? `${state.width}px` : state.width,
        },
        content: () => {
          // 滚动条元素
          const scrollNode = h(
            NScrollbar,
            {
              style: 'max-height: 80vh;',
            },
            () =>
              h(
                'div',
                { style: { paddingLeft: '5px' } },
                h(NFormBuilder, {
                  formItems: [],
                  ...props,
                  ref: formInstance,
                  modelValue: formData.value,
                  'onUpdate:modelValue': (newValue) => {
                    formData.value = cloneDeep(newValue as Record<string, unknown>)
                  },
                }),
              ),
          )

          // 弹框元素
          return h(
            'div',
            {
              class: 'edit-dia',
              style: {
                width: '100%',
              },
            },
            [
              h(MacHeader, {
                title: state.title,
                onClose: close,
              }),
              h(
                'div',
                { class: 'content' },
                diyTheme(() => scrollNode),
              ),
              diyTheme(() => toolNode),
            ],
          )
        },
      })
    } else {
      // 抽屉
      drawer.open(
        diyTheme(() =>
          h(NFormBuilder, {
            formItems: [],
            ...props,
            ref: (el) => {
              formInstance.value = el
            },
            modelValue: formData.value,
            'onUpdate:modelValue': (newValue) => {
              formData.value = cloneDeep(newValue as Record<string, unknown>)
            },
          }),
        ),
        {
          title: state.title,
          width: state.width,
          placement: 'right',
        },
        {
          footer: () => diyTheme(() => toolNode),
        },
      )
    }
  }
  return {
    formData,
    modal,
    open,
    setFormItems,
    setRules,
    setDefaultValue,
  }
}
